import {Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class WsService {
  private ws: WebSocket;
  private cbs: Map<Events, Callback> = new Map<Events, Callback>();
  private url: string;

  public init(url: string) {
    this.url = url;
    this.ws = new WebSocket(url);
    this.ws.onclose = ev => this.exec(ev, Events.ON_CLOSE);
    this.ws.onopen = e => this.exec(e, Events.ON_OPEN);
    this.ws.onerror = e => this.exec(e, Events.ON_ERROR);
    this.ws.onmessage = e => this.exec(e, Events.ON_MESSAGE);
  }

  public onOpen(cb: Callback) {
    this.cbs.set(Events.ON_OPEN, cb);
    return this;
  }

  public onClose(cb: Callback) {
    this.cbs.set(Events.ON_CLOSE, cb);
    return this;
  }

  public onError(cb: Callback) {
    this.cbs.set(Events.ON_ERROR, cb);
    return this;
  }

  public onMessage(cb: Callback) {
    this.cbs.set(Events.ON_MESSAGE, cb);
    return this;
  }

  private exec(ev: Event, es: Events) {
    if (this.cbs.has(es))
      this.cbs.get(es)(ev);
  }

  send(data: string) {
    this.ws.send(data);
  }
}

/**
 * 事件美枚举
 */
enum Events {
  ON_OPEN, ON_CLOSE, ON_MESSAGE, ON_ERROR
}

/**
 * 回调函数接口
 */
export interface Callback {
  (ev): void
}
